"""
文件名: logger.py
描述: 日志配置和管理模块

本模块包含以下主要功能：
1. 统一的日志配置管理
2. 多级别日志输出（DEBUG、INFO、WARNING、ERROR、CRITICAL）
3. 文件和控制台双重输出
4. 日志轮转和压缩
5. 结构化日志格式

依赖模块:
   - loguru: 现代化的Python日志库
   - pathlib: 路径操作
   - sys: 系统相关操作

使用示例:
   >>> from src.core.logger import logger
   >>> logger.info("应用启动成功")
   >>> logger.error("数据库连接失败", error="连接超时")

注意事项:
   - 日志文件会自动按日期轮转
   - 错误日志会单独存储到error目录
   - 敏感信息不要记录到日志中
   - 生产环境建议使用INFO级别

作者: AI助手
创建日期: 2024-06-27
最后修改: 2024-06-27
版本: 1.0.0
"""

import sys
from pathlib import Path
from typing import Dict, Any

from loguru import logger

from .config import get_settings

settings = get_settings()

# 日志目录
LOG_DIR = Path("logs")
LOG_DIR.mkdir(exist_ok=True)

# 应用日志目录
APP_LOG_DIR = LOG_DIR / "app"
ERROR_LOG_DIR = LOG_DIR / "error"
ACCESS_LOG_DIR = LOG_DIR / "access"
TASK_LOG_DIR = LOG_DIR / "task"

# 创建日志子目录
for log_dir in [APP_LOG_DIR, ERROR_LOG_DIR, ACCESS_LOG_DIR, TASK_LOG_DIR]:
    log_dir.mkdir(exist_ok=True)


def setup_logger() -> None:
    """
    配置日志系统
    
    配置包括：
    1. 控制台输出（带颜色）
    2. 应用日志文件（所有级别）
    3. 错误日志文件（ERROR及以上级别）
    4. 访问日志文件（API访问记录）
    5. 任务日志文件（Celery任务记录）
    """
    # 移除默认的处理器
    logger.remove()
    
    # 控制台输出配置
    logger.add(
        sys.stdout,
        format=settings.log_format,
        level=settings.log_level,
        colorize=True,
        backtrace=True,
        diagnose=True,
    )
    
    # 应用日志文件配置
    logger.add(
        APP_LOG_DIR / "app_{time:YYYY-MM-DD}.log",
        format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {name}:{function}:{line} | {message}",
        level="DEBUG",
        rotation="00:00",  # 每天轮转
        retention="30 days",  # 保留30天
        compression="zip",  # 压缩旧日志
        encoding="utf-8",
        backtrace=True,
        diagnose=True,
    )
    
    # 错误日志文件配置
    logger.add(
        ERROR_LOG_DIR / "error_{time:YYYY-MM-DD}.log",
        format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {name}:{function}:{line} | {message}",
        level="ERROR",
        rotation="00:00",
        retention="90 days",  # 错误日志保留更久
        compression="zip",
        encoding="utf-8",
        backtrace=True,
        diagnose=True,
    )
    
    # 访问日志文件配置（用于API访问记录）
    logger.add(
        ACCESS_LOG_DIR / "access_{time:YYYY-MM-DD}.log",
        format="{time:YYYY-MM-DD HH:mm:ss} | {message}",
        level="INFO",
        rotation="00:00",
        retention="30 days",
        compression="zip",
        encoding="utf-8",
        filter=lambda record: record["extra"].get("access_log", False),
    )
    
    # 任务日志文件配置（用于Celery任务记录）
    logger.add(
        TASK_LOG_DIR / "task_{time:YYYY-MM-DD}.log",
        format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {message}",
        level="INFO",
        rotation="00:00",
        retention="30 days",
        compression="zip",
        encoding="utf-8",
        filter=lambda record: record["extra"].get("task_log", False),
    )


def get_logger(name: str = __name__):
    """
    获取指定名称的日志记录器
    
    Args:
        name: 日志记录器名称，通常使用模块的__name__
        
    Returns:
        logger: 配置好的日志记录器实例
    """
    return logger.bind(name=name)


def log_api_access(
    method: str,
    path: str,
    status_code: int,
    response_time: float,
    user_id: str = None,
    ip: str = None,
    user_agent: str = None,
    **kwargs
) -> None:
    """
    记录API访问日志
    
    Args:
        method: HTTP方法
        path: 请求路径
        status_code: 响应状态码
        response_time: 响应时间（毫秒）
        user_id: 用户ID（可选）
        ip: 客户端IP（可选）
        user_agent: 用户代理（可选）
        **kwargs: 其他额外信息
    """
    log_data = {
        "method": method,
        "path": path,
        "status_code": status_code,
        "response_time": f"{response_time:.2f}ms",
        "user_id": user_id or "anonymous",
        "ip": ip or "unknown",
        "user_agent": user_agent or "unknown",
        **kwargs,
    }
    
    logger.bind(access_log=True).info(
        f"{method} {path} {status_code} {response_time:.2f}ms - {user_id or 'anonymous'}",
        **log_data
    )


def log_task_execution(
    task_name: str,
    task_id: str,
    status: str,
    execution_time: float = None,
    result: Any = None,
    error: str = None,
    **kwargs
) -> None:
    """
    记录Celery任务执行日志
    
    Args:
        task_name: 任务名称
        task_id: 任务ID
        status: 任务状态（PENDING、SUCCESS、FAILURE等）
        execution_time: 执行时间（秒）
        result: 任务结果
        error: 错误信息（如果失败）
        **kwargs: 其他额外信息
    """
    log_data = {
        "task_name": task_name,
        "task_id": task_id,
        "status": status,
        "execution_time": f"{execution_time:.2f}s" if execution_time else None,
        "result": str(result) if result else None,
        "error": error,
        **kwargs,
    }
    
    level = "ERROR" if status == "FAILURE" else "INFO"
    message = f"Task {task_name}[{task_id}] {status}"
    
    if execution_time:
        message += f" in {execution_time:.2f}s"
    
    logger.bind(task_log=True).log(level, message, **log_data)


# 初始化日志系统
setup_logger()

# 导出主要接口
__all__ = [
    "logger",
    "get_logger",
    "log_api_access",
    "log_task_execution",
    "setup_logger",
]